package fudan.se.lab2.service;

import fudan.se.lab2.controller.request.ApplyRequest;
import fudan.se.lab2.domain.*;
import fudan.se.lab2.exception.MeetingHasBeenAppliedException;
import fudan.se.lab2.exception.MeetingWrongStatusException;
import fudan.se.lab2.repository.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ChairService {
    private final MeetingRepository meetingRepository;
    private final DistributionRepository distributionRepository;
    private final PostRepository postRepository;
    private final ContributionRepository contributionRepository;
    private final RebuttalRepository rebuttalRepository;


    @Autowired
    public ChairService(MeetingRepository meetingRepository, DistributionRepository distributionRepository, PostRepository postRepository, ContributionRepository contributionRepository, RebuttalRepository rebuttalRepository) {
        this.meetingRepository = meetingRepository;
        this.distributionRepository = distributionRepository;
        this.postRepository = postRepository;
        this.contributionRepository = contributionRepository;
        this.rebuttalRepository = rebuttalRepository;
    }

    public Meeting apply(ApplyRequest request) {
        Meeting meeting = meetingRepository.findMeetingByFullName(request.getFull());
        if (meeting == null) {
            Meeting newMeeting = new Meeting(request.getAbbr(), request.getFull(), request.getChair(), request.getPc(), request.getDate(), request.getSpot(), request.getSubmit(), request.getResult(), 0, request.getTopics());
            meetingRepository.save(newMeeting);
            return newMeeting;
        } else {
            throw new MeetingHasBeenAppliedException(request.getFull());
        }
    }

    public Meeting allowContribute(String meetingFullName) {
        Meeting meeting = meetingRepository.findMeetingByFullName(meetingFullName);
        if (meeting.getStatus() == 1) {
            meeting.setStatus(2);
            meetingRepository.save(meeting);
            return meeting;
        } else {
            throw new MeetingWrongStatusException(meetingFullName);
        }
    }

    public boolean openReview(String meetingFullName) {
        Meeting meeting = meetingRepository.findMeetingByFullName(meetingFullName);
        if (meeting.getPcMembers().size() < 3)
            return false;
        if (meeting.getStatus() == 2) {
            meeting.setStatus(3);
            meetingRepository.save(meeting);
            return true;
        } else {
            throw new MeetingWrongStatusException(meetingFullName);
        }
    }

    public boolean closeReview(String meetingFullName) {//发布第一次审核结果
        Meeting meeting = meetingRepository.findMeetingByFullName(meetingFullName);
        if (meeting.getStatus() == 3) {
            Iterable<Distribution> distributions = distributionRepository.findByMeetingFullName(meetingFullName);
            for (Distribution distribution : distributions) {
                if (distribution.getStatus() != 2)
                    return false;
            }
            Iterable<Distribution> passDistributions;
            Iterable<Contribution> contributions = contributionRepository.findByMeetingFullName(meetingFullName);
            for (Contribution contribution : contributions) {
                if (contribution.getStatus() == 1) {
                    passDistributions = distributionRepository.findByFileTitleAndMeetingFullName(contribution.getFileTitle(), contribution.getMeetingFullName());
                    for (Distribution distribution : passDistributions)
                        distribution.setStatus(3);
                }
                contribution.setMeetingStatus(4);
                contributionRepository.save(contribution);
            }
            meeting.setStatus(4);
            meetingRepository.save(meeting);
            return true;
        } else {
            throw new MeetingWrongStatusException(meetingFullName);
        }
    }

    public boolean showSecondResult(String meetingFullName) {
        Meeting meeting = meetingRepository.findMeetingByFullName(meetingFullName);
        if (meeting.getStatus() == 4) {
            Iterable<Distribution> distributions = distributionRepository.findByMeetingFullName(meetingFullName);
            for (Distribution distribution : distributions) {
                if (distribution.getStatus() != 3)
                    return false;
            }
            Iterable<Contribution> contributions = contributionRepository.findByMeetingFullName(meetingFullName);
            for (Contribution contribution : contributions) {
                contribution.setMeetingStatus(5);
                contributionRepository.save(contribution);
            }
            meeting.setStatus(5);
            meetingRepository.save(meeting);
            return true;
        } else {
            throw new MeetingWrongStatusException(meetingFullName);
        }
    }


    public Post closeFirstPost(String meetingFullName, String title) {
        Iterable<Distribution> distributions = distributionRepository.findByFileTitleAndMeetingFullName(title, meetingFullName);
        for (Distribution distribution : distributions) {
            if (distribution.getStatus() != 2)
                return null;
        }
        Post post = postRepository.findByMeetingFullNameAndTitleAndType(meetingFullName, title, 1);
        post.setStatus(0);
        postRepository.save(post);
        return post;
    }

    public Post closeSecondPost(String meetingFullName, String title) {
        Iterable<Distribution> distributions = distributionRepository.findByFileTitleAndMeetingFullName(title, meetingFullName);
        for (Distribution distribution : distributions) {
            if (distribution.getStatus() != 3)
                return null;
        }

        Rebuttal rebuttal = rebuttalRepository.findByMeetingFullNameAndTitle(meetingFullName,title);
        rebuttal.setStatus(0);
        Post post = postRepository.findByMeetingFullNameAndTitleAndType(meetingFullName, title, 2);

        post.setStatus(0);
        postRepository.save(post);
        return post;
    }
}
